home *** CD-ROM | disk | FTP | other *** search
/ Aminet 30 / Aminet 30 (1999)(Schatztruhe)[!][Apr 1999].iso / Aminet / dev / lang / SmallEiffel.lha / SmallEiffel / lib_std / array.e < prev    next >
Text File  |  1998-12-22  |  8KB  |  316 lines

  1. -- This file is  free  software, which  comes  along  with  SmallEiffel. This
  2. -- software  is  distributed  in the hope that it will be useful, but WITHOUT 
  3. -- ANY  WARRANTY;  without  even  the  implied warranty of MERCHANTABILITY or
  4. -- FITNESS  FOR A PARTICULAR PURPOSE. You can modify it as you want, provided
  5. -- this header is kept unaltered, and a notification of the changes is added.
  6. -- You  are  allowed  to  redistribute  it and sell it, alone or as a part of 
  7. -- another product.
  8. --          Copyright (C) 1994-98 LORIA - UHP - CRIN - INRIA - FRANCE
  9. --            Dominique COLNET and Suzanne COLLIN - colnet@loria.fr 
  10. --                       http://www.loria.fr/SmallEiffel
  11. --
  12. class ARRAY[E]
  13.    -- 
  14.    -- General purpose resizable ARRAYs.
  15.    -- 
  16.  
  17. inherit ARRAYED_COLLECTION[E];
  18.  
  19. creation make, with_capacity, from_collection
  20.  
  21. feature
  22.    
  23.    lower: INTEGER;     
  24.      -- Lower index bound.
  25.    
  26. feature -- Creation and Modification :
  27.    
  28.    make(minindex, maxindex: INTEGER) is
  29.      -- Make array with range [`minindex' .. `maxindex']. 
  30.      -- When `maxindex' = `minindex' - 1, the array is empty.
  31.       require
  32.      minindex -1 <= maxindex
  33.       local
  34.      needed: INTEGER;
  35.       do
  36.      lower := minindex;
  37.      upper := maxindex;
  38.      needed := maxindex - minindex + 1;
  39.      if needed > 0 then
  40.         if capacity < needed then
  41.            storage := storage.calloc(needed);
  42.            capacity := needed;
  43.         else
  44.            clear_all;
  45.         end;
  46.      end;
  47.       ensure
  48.      lower = minindex;
  49.      upper = maxindex;
  50.      all_cleared
  51.       end;
  52.  
  53.    with_capacity(needed_capacity, low: INTEGER) is
  54.      -- Create an empty array with `capacity' initialized
  55.      -- at least to `needed_capacity' and `lower' set to `low'.
  56.       require
  57.      needed_capacity >= 0
  58.       do
  59.      if capacity < needed_capacity then
  60.         storage := storage.calloc(needed_capacity);
  61.         capacity := needed_capacity;
  62.      end;
  63.      lower := low;
  64.      upper := low - 1;
  65.       ensure
  66.      empty;
  67.      needed_capacity <= capacity;
  68.      lower = low
  69.       end;
  70.  
  71. feature -- Modification :
  72.    
  73.    resize(minindex, maxindex: INTEGER) is
  74.      -- Resize the array. No elements will be lost in the 
  75.      -- intersection of [old `lower' .. old `upper'] and 
  76.      -- [`minindex' .. `maxindex'].
  77.      -- New positions are initialized with appropriate 
  78.      -- default values.
  79.       require
  80.          minindex -1 <= maxindex
  81.       local
  82.          needed, offset, intersize: INTEGER;
  83.       do
  84.          needed := maxindex - minindex + 1;
  85.          if needed > 0 then
  86.             if needed > capacity then
  87.                if capacity = 0 then
  88.                   storage := storage.calloc(needed);
  89.                   capacity := needed;
  90.                else
  91.                   storage := storage.realloc(capacity, needed);
  92.                   capacity := needed;
  93.                end;
  94.             end;
  95.             offset := lower - minindex;
  96.             intersize := maxindex.min(upper) - minindex.max(lower) + 1;
  97.             if intersize > 0 then
  98.                if offset = 0 then
  99.                   if intersize < needed then
  100.                      storage.clear(intersize, needed - 1);
  101.                   end;
  102.                elseif offset < 0 then
  103.                   storage.move(-offset, intersize - offset - 1, offset);
  104.                   if intersize < needed then
  105.                      storage.clear(intersize, needed - 1);
  106.                   end;
  107.                else
  108.                   storage.move(0, intersize - 1, offset);
  109.                   storage.clear(0, offset - 1);
  110.                   if intersize + offset < needed then
  111.                      storage.clear(intersize + offset, needed - 1);
  112.                   end;
  113.                end;
  114.             else
  115.                storage.clear(0, needed - 1);
  116.             end;
  117.          end;
  118.          lower := minindex;
  119.          upper := maxindex;
  120.       end;
  121.  
  122. feature 
  123.  
  124.    sub_array(low, up: INTEGER): like Current is
  125.       local
  126.      i: INTEGER;
  127.       do
  128.      from
  129.         !!Result.with_capacity(up - low + 1,low);
  130.         Result.set_upper(up);
  131.         i := low;
  132.      until
  133.         i > up
  134.      loop
  135.         Result.put(item(i),i);
  136.         i := i + 1;
  137.      end;
  138.       ensure then
  139.      Result.lower = low;
  140.       end;
  141.  
  142. feature -- Implementation of deferred :
  143.  
  144.    count: INTEGER is
  145.       do
  146.      Result := upper - lower + 1;
  147.       end;
  148.  
  149.    item, infix "@" (index: INTEGER): E is
  150.       do
  151.      Result := storage.item(index - lower);
  152.       end;
  153.    
  154.    put(element: like item; index: INTEGER) is
  155.       do
  156.      storage.put(element,index - lower);
  157.       end;
  158.  
  159.    force(element: like item; index: INTEGER) is
  160.      -- Put `element' at position `index'. Current is
  161.      -- resized if `index' is not inside current bounds.
  162.      -- New bounds are initialized with default values.
  163.       require else
  164.      true
  165.       do
  166.      if upper < index then
  167.         resize(lower,index);
  168.      elseif index < lower then
  169.         resize(index,upper);
  170.      end;
  171.      put(element,index);
  172.       end;
  173.  
  174.    copy(other: like Current) is
  175.       local
  176.      needed_capacity: INTEGER;
  177.       do
  178.      lower := other.lower;
  179.      upper := other.upper;
  180.      needed_capacity := upper - lower + 1;
  181.      if capacity < needed_capacity then
  182.         capacity := needed_capacity;
  183.         storage := storage.calloc(capacity);
  184.      end;
  185.      if needed_capacity > 0 then
  186.         storage.copy_from(other.storage,needed_capacity - 1);
  187.      end;
  188.       end;
  189.    
  190.    set_all_with(v: like item) is
  191.       do
  192.      storage.set_all_with(v,upper - lower);
  193.       end;
  194.  
  195.    remove_first is
  196.       do
  197.      storage.remove_first(upper - lower);
  198.      lower := lower + 1;
  199.       ensure then
  200.      upper = old upper;
  201.       end;
  202.    
  203.    remove(index: INTEGER) is
  204.       do
  205.      storage.remove(index - lower,upper - lower);
  206.      upper := upper - 1;
  207.       end;
  208.    
  209.    clear is
  210.       do
  211.      upper := lower - 1;
  212.       ensure then
  213.      capacity = old capacity
  214.       end;
  215.  
  216.    add_first(element: like item) is
  217.       do
  218.      if upper < lower then
  219.         add_last(element);
  220.      else
  221.         add_last(element);
  222.         move(lower,upper - 1,1);
  223.         put(element,lower);
  224.      end;
  225.       end;
  226.  
  227.    add_last(element: like item) is
  228.       local
  229.      new_capacity: INTEGER;
  230.       do
  231.      if capacity < count + 1 then
  232.         if capacity = 0 then
  233.            capacity := 16;
  234.            storage := storage.calloc(capacity);
  235.         else
  236.            new_capacity := 2 * capacity;
  237.            storage := storage.realloc(capacity,new_capacity);
  238.            capacity := new_capacity;
  239.         end;
  240.      end;
  241.      upper := upper + 1;
  242.      put(element,upper);
  243.       end;
  244.  
  245.    from_collection(model: COLLECTION[like item]) is
  246.       local
  247.      i, up: INTEGER;
  248.       do
  249.      from
  250.         with_capacity(model.count,model.lower);
  251.         i := model.lower;
  252.         up := model.upper;
  253.         upper := up;
  254.      until
  255.         i > up
  256.      loop
  257.         put(model.item(i),i);
  258.         i := i + 1;
  259.      end;
  260.       ensure then
  261.      lower = model.lower;
  262.      upper = model.upper
  263.       end;
  264.  
  265.    all_cleared: BOOLEAN is
  266.       do
  267.      Result := storage.all_cleared(upper - lower);
  268.       end;
  269.  
  270.    nb_occurrences(element: like item): INTEGER is
  271.       do
  272.      Result := storage.nb_occurrences(element,upper - lower);
  273.       end;
  274.       
  275.    fast_nb_occurrences(element: like item): INTEGER is
  276.       do
  277.      Result := storage.fast_nb_occurrences(element,upper - lower);
  278.       end;
  279.       
  280.    index_of(element: like item): INTEGER is
  281.       do
  282.      Result := lower + storage.index_of(element,upper - lower);
  283.       end;
  284.  
  285.    fast_index_of(element: like item): INTEGER is
  286.       do
  287.      Result := lower + storage.fast_index_of(element,upper - lower);
  288.       end;
  289.  
  290.    is_equal(other: like Current): BOOLEAN is
  291.       do
  292.      if Current = other then
  293.         Result := true;
  294.      elseif lower = other.lower and then upper = other.upper then
  295.         Result := storage.memcmp(other.storage,count);
  296.      end;
  297.       end;
  298.  
  299.    slice(low, up: INTEGER): like Current is
  300.       local
  301.      i: INTEGER;
  302.       do
  303.      from
  304.         i := low;
  305.         !!Result.with_capacity(up - low + 1,lower);
  306.      until
  307.         i > up
  308.      loop
  309.         Result.add_last(item(i));
  310.         i := i + 1;
  311.      end;
  312.       end;
  313.  
  314. end -- ARRAY[E]
  315.  
  316.